#!/usr/bin/python
#! -- coding:utf-8 --
from BeautifulSoup import BeautifulSoup
from lxml import etree
from splinter import Browser
import re

def IdentifyApp(url):
    # identify web application 
    # @arguement:url
    # @return:web application name or None
    browser=Browser("phantomjs")
    browser.visit(url)
    '''     it depends on meta tag
           it can identify Discuz!,Wordpress,Joomla and so on
    '''
    soup=BeautifulSoup(browser.html)
    cookies=browser.cookies.all()
    browser.quit()
    
    head=soup.find('head')
    try:
        app=head.find(name="meta",attrs={"name":"generator"})['content']
        return app
    except:
        pass
    
    '''     it depends on general markers like "powered by xxx","build on xxx","running xxx"
           it can identy ZK,Discuz and so on
    '''
    words_list=["powered by","built on","running"]
    body=soup.find("body")
    try:
        for keyword in words_list:
            signal=body.find(text=re.compile(keyword,re.I)).parent
            et=etree.XML(''' %s''' % signal)
            sigwh=etree.tostring(et,method="text")
            return re.search("%s (.*)" % keyword,sigwh,re.I).group(1)
    except:
        pass
    
    '''    it depends on Specific markers like "ZK","JTBC" and so on
          it can identify ZK framework,JTBC
    '''
    markers_list={"<!-- ZK":"ZK","<!--JTBC":"JTBC","__VIEWSTATE":"ASP.NET"}
    try:
        val=""
        for (marker,value) in markers_list.items():
            if  str(body).find(marker)!=-1:
                if val=="":
                    val=value
                else:
                    val="%s,%s" %(val,value)
        if val!="":
            return val
    except:
        pass
    
    """    it depends on cookies
            it can identify cakephp
    """
    cookies_list={"cakephp":"cakephp"}
    for (cookie,value) in cookies_list.items():
        for ind in cookies:
            for (name,v) in ind.items():
                if name.lower().encode("utf-8")=="name" and v.lower().encode("utf-8")==cookie:
                    return value
                
    """     it depends on specific files and folders
    """
    #   code here 
    
    return None
